package im.yangqiang.android.unicorn.retrofit;

import android.util.Log;

import java.io.File;
import java.io.IOException;
import java.util.HashMap;
import java.util.concurrent.TimeUnit;

import im.yangqiang.android.unicorn.http.IProgressListener;
import okhttp3.Call;
import okhttp3.Callback;
import okhttp3.MediaType;
import okhttp3.MultipartBody;
import okhttp3.OkHttpClient;
import okhttp3.Request;
import okhttp3.RequestBody;
import okhttp3.Response;
import okio.Buffer;
import okio.BufferedSink;
import okio.Okio;
import okio.Source;

/**
 * 文件上传
 * Created by Carlton on 16/9/13.
 */

public class FileUpload
{
    private static final String TAG = "FileUpload";

    /**
     * 上传文件
     *
     * @param url       接口地址
     * @param paramsMap 参数
     * @param callBack  回调
     */
    public static void upLoadFile(String url, HashMap<String, Object> paramsMap, final IProgressListener callBack)
    {
        try
        {
            MultipartBody.Builder builder = new MultipartBody.Builder();
            //设置类型
            builder.setType(MultipartBody.FORM);
            //追加参数
            for (String key : paramsMap.keySet())
            {
                Object object = paramsMap.get(key);
                if (!(object instanceof File))
                {
                    builder.addFormDataPart(key, object.toString());
                } else
                {
                    File file = (File) object;
                    builder.addFormDataPart(key, file.getName(), createProgressRequestBody(MediaType.parse("application/octet-stream"), file, callBack));
                }
            }
            //创建RequestBody
            RequestBody body = builder.build();
            //创建Request
            final Request request = new Request.Builder().url(url).post(body).build();
            final Call call = new OkHttpClient.Builder().build().newBuilder().writeTimeout(50, TimeUnit.SECONDS).build().newCall(request);
            call.enqueue(new Callback()
            {
                @Override
                public void onFailure(Call call, IOException e)
                {
                    Log.d(TAG, e.toString());
                    callBack.onError(e);
                }

                @Override
                public void onResponse(Call call, Response response) throws IOException
                {
                    if (response.isSuccessful())
                    {
                        String string = response.body().string();
                        Log.d(TAG, "response ----->" + string);
                        callBack.onFinish(string);
                    } else
                    {
                        callBack.onError(new RuntimeException("上传失败"));
                    }
                }
            });
        }
        catch (Exception e)
        {
            Log.d(TAG, e.toString());
        }
    }

    /**
     * 创建带进度的RequestBody
     *
     * @param contentType MediaType
     * @param file        准备上传的文件
     * @param callBack    回调
     * @return
     */
    private static RequestBody createProgressRequestBody(final MediaType contentType, final File file, final IProgressListener callBack)
    {
        return new RequestBody()
        {
            @Override
            public MediaType contentType()
            {
                return contentType;
            }

            @Override
            public long contentLength()
            {
                return file.length();
            }

            @Override
            public void writeTo(BufferedSink sink) throws IOException
            {
                Source source;
                try
                {
                    source = Okio.source(file);
                    Buffer buf = new Buffer();
                    long remaining = contentLength();
                    long current = 0;
                    long readCount;
                    while ((readCount = source.read(buf, 2048)) != -1)
                    {
                        sink.write(buf, readCount);
                        current += readCount;
                        Log.d(TAG, "current------>" + current);
                        callBack.onProgress(remaining, current);
                    }
                }
                catch (Exception e)
                {
                    e.printStackTrace();
                    callBack.onError(e);
                }
            }
        };
    }
}